package com.example.dormitorysystem.service.impl;

import com.auth0.jwt.interfaces.Claim;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dormitorysystem.common.jwt.JwtUtil;
import com.example.dormitorysystem.entity.Auth;
import com.example.dormitorysystem.exception.CmsException;
import com.example.dormitorysystem.exception.ErrorCode;
import com.example.dormitorysystem.mapper.AuthMapper;
import com.example.dormitorysystem.mapper.UsersMapper;
import com.example.dormitorysystem.service.AuthService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dormitorysystem.utils.RedisUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 吉吉王国组
 * @since 2022-11-13
 */
@Service
public class AuthServiceImpl extends ServiceImpl<AuthMapper, Auth> implements AuthService {

    private static String TOKEN = "TOKEN_";
    private static String REFRESH_TOKEN = "REFRESH_TOKEN_";
    private static String USER_AGENT = "USER_AGENT_";


    @Resource
    private RedisUtil redisUtil;

    @Resource
    private UsersMapper usersMapper;


    @Override
    public Map<String, Object> login(Map<String, Object> loginInput, HttpServletRequest request, HttpServletResponse response) {
        String username = (String) loginInput.get("username");
        String password = (String) loginInput.get("password");

        if (username == null || password == null) {
            throw new CmsException(ErrorCode.INCOMPLETE_PARAMETER);
        }

        QueryWrapper<Auth> wrapper = new QueryWrapper<>();
        //查询条件，对数据库进行查询'user_number' 等于输入的学号
        wrapper.eq("username", username);
        Auth auth = baseMapper.selectOne(wrapper);

        // 判断用户是否存在
        if (auth == null) {
            throw new CmsException(ErrorCode.NO_SUCH_USER);
        } else if (!auth.getPassword().matches(password)) {
            throw new CmsException(ErrorCode.WRONG_ACCOUNT_OR_PASSWORD);
        }
        // 用户账号已停用
        if (auth.getIsDel() == 1) {
            throw new CmsException(ErrorCode.NO_SUCH_USER);
        }

        String user_agent = request.getHeader("User-Agent");

        String token = JwtUtil.createToken(auth.getUid(), username, password);

        String refresh_token = UUID.randomUUID() + "";

        // <refresh_token, uid>
        redisUtil.set(REFRESH_TOKEN + refresh_token, auth.getUid(), 7 * 24 * 60);

        // <uid, refresh_token>
        redisUtil.set(auth.getUid().toString(), REFRESH_TOKEN + refresh_token, 7 * 24 * 60);

        // <uid, USER_AGENT>
        redisUtil.set(USER_AGENT + auth.getUid(), user_agent);
        redisUtil.set(TOKEN + auth.getUid(), token);

        usersMapper.updateLoginTime(new Date(), auth.getUid());

        // 返回数据
        Map<String, Object> res = new HashMap<>();
        res.put("access_token", token);
        res.put("refresh_token", refresh_token);
        res.put("expires_in", 7200);
        res.put("token_type", "bearer");
        return res;
    }

    @Override
    public Map<String, Object> refreshToken(String token, String refresh_token, HttpServletRequest request, HttpServletResponse response) {

        Integer id = (Integer) redisUtil.get(REFRESH_TOKEN + refresh_token);
        // refresh_token expire
        if (id == null) {
            throw new CmsException(ErrorCode.ACCOUNT_HAVE_RISK);
        }

        String old_refresh_token = (String) redisUtil.get(id.toString());
        System.out.println(old_refresh_token);
        // refresh_token expire
        if (old_refresh_token == null) {
            throw new CmsException(ErrorCode.ACCOUNT_HAVE_RISK);
        }

        String old_user_agent = (String) redisUtil.get(USER_AGENT + id);
        System.out.println(old_user_agent);

        String user_agent = request.getHeader("User-Agent");
        System.out.println(user_agent);

        if (token == null || old_user_agent == null || !old_user_agent.equals(user_agent)) {
            throw new CmsException(ErrorCode.ACCOUNT_HAVE_RISK);
        }
        if (!old_refresh_token.equals(REFRESH_TOKEN + refresh_token)) {
            throw new CmsException(201, "ninde zhanghao youfengxiang");
            //throw new CmsException(ErrorCode.ACCOUNT_HAVE_RISK);
        }

        // generate new token
        Map<String, Claim> userData = JwtUtil.verifyToken(token);

        String uid = userData.get("uid").asString();
        String userName = userData.get("username").asString();
        String password = userData.get("password").asString();

        token = JwtUtil.createToken(Integer.parseInt(uid), userName, password);
        refresh_token = UUID.randomUUID() + "";

        // <refresh_token, id>
        redisUtil.set(REFRESH_TOKEN + refresh_token, id, 3 * 24 * 60 * 60);

        // <refresh_token, id>
        redisUtil.set(id.toString(), REFRESH_TOKEN + refresh_token, 3 * 24 * 60 * 60);

        // 返回数据
        Map<String, Object> res = new HashMap<>();
        res.put("token", token);
        res.put("refresh_token", refresh_token);
        res.put("expire", 7200);
        return res;
    }

    @Override
    public void logout(HttpServletRequest request) {
        // 返回数据
        Integer id = Integer.parseInt(request.getAttribute("uid").toString());
        redisUtil.expire(TOKEN + id, 0);
    }

}
